home *** CD-ROM | disk | FTP | other *** search
/ The Games Machine 80 / XENIATGM80.iso / Goodies / Blood 2 / Source / data.z / BaseCharacter.cpp < prev    next >
C/C++ Source or Header  |  1999-04-02  |  11KB  |  462 lines

  1. // ----------------------------------------------------------------------- //
  2. //
  3. // MODULE  : BaseCharacter.cpp
  4. //
  5. // PURPOSE : Base class for player and AI
  6. //
  7. // CREATED : 10/6/97
  8. //
  9. // ----------------------------------------------------------------------- //
  10.  
  11. #include "BaseCharacter.h"
  12. #include "objectutilities.h"
  13. #include "VolumeBrush.h"
  14. #include "ClientServerShared.h"
  15. #include "SParam.h"
  16. #include "PlayerObj.h"
  17. #include <stdio.h>
  18.  
  19.  
  20. //#define FLAG_BASECHARACTER        1
  21. //#define FLAG_PLAYER                2
  22.  
  23. #define LADDER_STOP_TIME            0.2f
  24. #define SWIM_STOP_TIME                1.0f
  25.  
  26.  
  27. BEGIN_CLASS(CBaseCharacter)
  28.     ADD_DESTRUCTABLE_AGGREGATE()
  29. END_CLASS_DEFAULT(CBaseCharacter, B2BaseClass, NULL, NULL)
  30.  
  31.  
  32. CBaseCharacter::CBaseCharacter(DBYTE nType) : B2BaseClass(nType)
  33. {
  34.      AddAggregate(&m_damage);
  35.     AddAggregate(&m_InventoryMgr);
  36.     AddAggregate(&m_MoveObj);
  37.  
  38.     m_eContainerCode            = CC_NOTHING;
  39.     m_eLastContainerCode        = CC_NOTHING;
  40.     m_bBodyInLiquid                = DFALSE;
  41.     m_bBodyOnLadder                = DFALSE;
  42.     m_bSwimmingOnSurface        = DFALSE;
  43.  
  44.     m_dwSurfType                = SURFTYPE_FLESH;
  45.  
  46.     m_fSwimVel                    = DEFAULT_SWIM_VEL;
  47.     m_fLadderVel                = DEFAULT_LADDER_VEL;
  48.  
  49.     m_nTrapped                    = 0;
  50.     m_bTrappedGrav                = DTRUE;
  51. }
  52.  
  53.  
  54.  
  55. DDWORD CBaseCharacter::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
  56. {
  57.     switch(messageID)
  58.     {
  59.         case MID_UPDATE:
  60.             m_eLastContainerCode = m_eContainerCode;
  61.             break;
  62.  
  63.         case MID_MODELSTRINGKEY:
  64.         {
  65.             OnStringKey((ArgList*)pData);
  66.             break;
  67.         }
  68.  
  69.         case MID_SAVEOBJECT:
  70.             Save((HMESSAGEWRITE)pData, (DDWORD)fData);
  71.             break;
  72.  
  73.         case MID_LOADOBJECT:
  74.             Load((HMESSAGEREAD)pData, (DDWORD)fData);
  75.             break;
  76.  
  77.         case MID_INITIALUPDATE:
  78.             {
  79.                 if (fData != INITIALUPDATE_SAVEGAME)
  80.                 {
  81.                     // Set some flags that all basecharacters should have
  82.                     // Doing it here for now since I don't want to change every AI file - GK 3/18
  83.                     DDWORD dwFlags = g_pServerDE->GetObjectFlags(m_hObject);
  84.                     g_pServerDE->SetObjectFlags(m_hObject, dwFlags | FLAG_MODELGOURAUDSHADE | FLAG_ANIMTRANSITION);
  85.                     g_pServerDE->SetObjectUserFlags(m_hObject, USERFLG_NIGHTGOGGLESGLOW );
  86.  
  87.                     dwFlags = g_pServerDE->GetObjectUserFlags(m_hObject);
  88.                     dwFlags |= ((m_dwSurfType << 24) + USRFLG_SAVEABLE | USRFLG_SINGULARITY_ATTRACT);
  89.                      g_pServerDE->SetObjectUserFlags(m_hObject, dwFlags);
  90.                 }
  91.             }
  92.             break;
  93.  
  94.         default : break;
  95.     }
  96.  
  97.     return B2BaseClass::EngineMessageFn(messageID, pData, fData);
  98. }
  99.  
  100. // ----------------------------------------------------------------------- //
  101. //
  102. //    ROUTINE:    CBaseCharacter::OnStringKey()
  103. //
  104. //    PURPOSE:    Handle animation command
  105. //
  106. // ----------------------------------------------------------------------- //
  107.  
  108. void CBaseCharacter::OnStringKey(ArgList* pArgList)
  109. {
  110.     CServerDE* pServerDE = GetServerDE();
  111.     if (!pServerDE || !pArgList || !pArgList->argv || pArgList->argc == 0) return;
  112.  
  113.     char* pKey = pArgList->argv[0];
  114.     if (!pKey) return;
  115.  
  116.     // get rotation
  117.     DRotation rRot;
  118.     DVector m_vUp, m_vRight, m_vForward;
  119.     
  120.     VEC_INIT(m_vUp);
  121.     VEC_INIT(m_vRight);
  122.     VEC_INIT(m_vForward);
  123.  
  124.     char szTemp[32];
  125.  
  126.     //check for direction change for velocity 
  127.     if(Sparam_Get(szTemp,pKey,"RotY"))
  128.     {
  129.         DFLOAT fTurn = (DFLOAT)atof(szTemp);
  130.  
  131.         pServerDE->GetObjectRotation(m_hObject, &rRot);
  132.         pServerDE->EulerRotateY(&rRot, fTurn);
  133.         pServerDE->SetObjectRotation(m_hObject, &rRot);    
  134.     }
  135.  
  136.     //check for forward/backward velocity
  137.     if(Sparam_Get(szTemp,pKey,"ForwVel"))
  138.     {
  139.         pServerDE->GetObjectRotation(m_hObject, &rRot);
  140.         pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);
  141.  
  142.         DVector vVel;
  143.         VEC_MULSCALAR(vVel, m_vForward, (DFLOAT)atof(szTemp));
  144.  
  145.         pServerDE->SetVelocity(m_hObject, &vVel);
  146.     }
  147.  
  148.     //check for right/left velocity
  149.     if(Sparam_Get(szTemp,pKey,"RightVel"))
  150.     {
  151.         pServerDE->GetObjectRotation(m_hObject, &rRot);
  152.         pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);
  153.  
  154.         DVector vVel;
  155.         VEC_MULSCALAR(vVel, m_vRight, (DFLOAT)atof(szTemp));
  156.  
  157.         pServerDE->SetVelocity(m_hObject, &vVel);
  158.     }
  159.  
  160.  
  161.     //check for up/down velocity
  162.     if(Sparam_Get(szTemp,pKey,"UpVel"))
  163.     {
  164.         pServerDE->GetObjectRotation(m_hObject, &rRot);
  165.         pServerDE->GetRotationVectors(&rRot, &m_vUp, &m_vRight, &m_vForward);
  166.  
  167.         DVector vVel;
  168.         VEC_MULSCALAR(vVel, m_vUp, (DFLOAT)atof(szTemp));
  169.  
  170.         pServerDE->SetVelocity(m_hObject, &vVel);
  171.     }
  172.  
  173.     //check for position change
  174.     if(Sparam_Get(szTemp,pKey,"AddX"))
  175.     {
  176.         DVector vPos,vNewPos;
  177.         char szY[10],szZ[10];
  178.  
  179.         Sparam_Get(szY,pKey,"AddY");
  180.         Sparam_Get(szZ,pKey,"AddZ");
  181.  
  182.         VEC_INIT(vPos);
  183.         VEC_SET(vNewPos, atof(szTemp), atof(szY), atof(szZ));
  184.         pServerDE->GetObjectPos(m_hObject, &vPos);
  185.         VEC_ADD(vPos,vPos,vNewPos);
  186.  
  187.         //apply new dims
  188.         pServerDE->MoveObject(m_hObject, &vPos);
  189.     }
  190.  
  191.     //check for dims change
  192.     if(Sparam_Get(szTemp,pKey,"DimsX"))
  193.     {
  194.         DVector vDims;
  195.         char szY[10],szZ[10];
  196.  
  197.         Sparam_Get(szY,pKey,"DimsY");
  198.         Sparam_Get(szZ,pKey,"DimsZ");
  199.  
  200.         VEC_INIT(vDims);
  201.         VEC_SET(vDims, atof(szTemp), atof(szY), atof(szZ));
  202.         
  203.         //apply new dims
  204.         pServerDE->SetObjectDims(m_hObject, &vDims);
  205.     }
  206.  
  207.     return;
  208. }
  209.  
  210.  
  211. // ----------------------------------------------------------------------- //
  212. //
  213. //    ROUTINE:    CBaseCharacter::Trap
  214. //
  215. //    PURPOSE:    Don't allow a player to move (with or without gravity)
  216. //
  217. // ----------------------------------------------------------------------- //
  218.  
  219. DBOOL CBaseCharacter::Trap(char nTrap, DBOOL bGravity)
  220. {
  221.     CServerDE* pServerDE = GetServerDE();
  222.     if (!pServerDE || !m_hObject) return DFALSE;
  223.  
  224.     // Modify the trapped counter...
  225.     if(nTrap == -1)
  226.     {
  227.         m_nTrapped = 0;
  228.         nTrap = 0;
  229.     }
  230.     else if(nTrap)
  231.         m_nTrapped++;
  232.     else
  233.         m_nTrapped--;
  234.  
  235.     // Don't let the trapped counter drop below zero...
  236.     if(m_nTrapped < 0)
  237.         m_nTrapped = 0;
  238.  
  239.     // Zero out the current velocity
  240.     if(nTrap)
  241.     {
  242.         DVector vTemp;
  243.         VEC_INIT(vTemp);
  244.  
  245.         if(!bGravity)
  246.         {
  247.             pServerDE->GetVelocity(m_hObject, &vTemp);
  248.             vTemp.x = vTemp.z = 0.0f;
  249.         }
  250.  
  251.         pServerDE->SetVelocity(m_hObject, &vTemp);
  252.         pServerDE->SetNextUpdate(m_hObject, 0.0001f);
  253.     }
  254.  
  255.     // Trap the client if it's a player
  256.     if(IsPlayer(m_hObject))
  257.     {
  258.         CPlayerObj *pHit = (CPlayerObj*)pServerDE->HandleToObject(m_hObject);
  259.  
  260.         HMESSAGEWRITE hMsg = pServerDE->StartMessage(pHit->GetClient(), SMSG_TRAPPED);
  261.         pServerDE->WriteToMessageByte(hMsg, (DBYTE)m_nTrapped);
  262.         pServerDE->WriteToMessageByte(hMsg, 1);
  263.         pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED | MESSAGE_NAGGLE);
  264.     }
  265.  
  266.     // Save or restore the original gravity setting if needed
  267. /*    if(bGravity)
  268.     {
  269.         DDWORD    dwFlags;
  270.         dwFlags = pServerDE->GetObjectFlags(m_hObject);
  271.  
  272.         if(nTrap && (m_nTrapped == 1))
  273.         {
  274.             m_bTrappedGrav = (DBOOL)(dwFlags & FLAG_GRAVITY);
  275.             pServerDE->SetObjectFlags(m_hObject, dwFlags & ~FLAG_GRAVITY);
  276.         }
  277.         else if(!nTrap && !m_nTrapped && m_bTrappedGrav)
  278.         {
  279.             pServerDE->SetObjectFlags(m_hObject, dwFlags | FLAG_GRAVITY);
  280.         }
  281.     }*/
  282.  
  283.     return DTRUE;
  284. }
  285.  
  286.  
  287. // ----------------------------------------------------------------------- //
  288. //
  289. //    ROUTINE:    CBaseCharacter::UpdateInLiquid
  290. //
  291. //    PURPOSE:    Update movement when in liquid
  292. //
  293. // ----------------------------------------------------------------------- //
  294.  
  295. void CBaseCharacter::UpdateInLiquid(VolumeBrush* pBrush, ContainerPhysics* pCPStruct)
  296. {
  297.     CServerDE* pServerDE = GetServerDE();
  298.     if (!pServerDE || !pBrush || !pCPStruct) return;
  299.  
  300.     m_bBodyInLiquid = DTRUE;
  301.  
  302.     DBOOL bHeadInLiquid = IsLiquid(m_eContainerCode);
  303.  
  304.     // Undo viscosity dampening done in brush (we'll do our own)...
  305.  
  306.     pBrush->UndoViscosityCalculation(pCPStruct);
  307.  
  308.  
  309.     // Do REAL friction dampening (i.e., actually change our velocity)...
  310.  
  311.     DVector vVel;
  312.     pServerDE->GetVelocity(m_hObject, &vVel);
  313.  
  314.     DFLOAT fTimeDelta = pServerDE->GetFrameTime();
  315.  
  316.     DVector vCurVel;
  317.     VEC_COPY(vCurVel, vVel);
  318.  
  319.     if (VEC_MAG(vCurVel) > 1.0f)
  320.     {
  321.         DVector vDir;
  322.         VEC_COPY(vDir, vCurVel);
  323.         VEC_NORM(vDir);
  324.  
  325.         DFLOAT fAdjust = pServerDE->GetFrameTime()*(m_fSwimVel/SWIM_STOP_TIME);
  326.  
  327.         VEC_MULSCALAR(vVel, vDir, fAdjust);
  328.  
  329.         if (VEC_MAG(vVel) < VEC_MAG(vCurVel))
  330.         {
  331.             VEC_SUB(vVel, vCurVel, vVel);
  332.         }
  333.         else
  334.         {
  335.             VEC_INIT(vVel);
  336.         }
  337.     }
  338.  
  339.  
  340.     // Handle floating around on the surface...
  341.  
  342.     if (m_bSwimmingOnSurface)
  343.     {
  344.         DBOOL bMoving = ((VEC_MAG(pCPStruct->m_Acceleration) > 0.01f) ||
  345.                          (VEC_MAG(pCPStruct->m_Velocity) > 0.01f));
  346.     
  347.         pCPStruct->m_Flags &= ~FLAG_GRAVITY;  // Turn gravity off
  348.  
  349.         if (bMoving)  // Turn off y acceleration and velocity
  350.         {
  351.             if (vVel.y > 0.0f || pCPStruct->m_Acceleration.y > 0.0f)
  352.             {
  353.                 vVel.y                        = 0.0f;
  354.                 pCPStruct->m_Velocity.y        = 0.0f;
  355.                 pCPStruct->m_Acceleration.y = 0.0f;
  356.             }
  357.         }
  358.         else // Pull us down if we're not moving (fast enough)
  359.         {
  360.             pCPStruct->m_Acceleration.y += pBrush->GetGravity();
  361.         }
  362.     }
  363.     else if (IsLiquid(m_eContainerCode))
  364.     {
  365.         pCPStruct->m_Flags &= ~FLAG_GRAVITY;
  366.         pCPStruct->m_Acceleration.y += pBrush->GetGravity();
  367.     }
  368.  
  369.     // If we're trapped, don't move...
  370.     if(m_nTrapped)
  371.         { VEC_INIT(vVel); }
  372.  
  373.     pServerDE->SetVelocity(m_hObject, &vVel);
  374. }
  375.  
  376.  
  377. // ----------------------------------------------------------------------- //
  378. //
  379. //    ROUTINE:    CBaseCharacter::UpdateOnLadder
  380. //
  381. //    PURPOSE:    Update movement when on a ladder
  382. //
  383. // ----------------------------------------------------------------------- //
  384.  
  385. void CBaseCharacter::UpdateOnLadder(VolumeBrush* pBrush, ContainerPhysics* pCPStruct)
  386. {
  387.     CServerDE* pServerDE = GetServerDE();
  388.     if (!pServerDE || !pBrush || !pCPStruct) return;
  389.  
  390.     m_bBodyOnLadder = DTRUE;
  391.  
  392.     // Do REAL friction dampening (i.e., actually change our velocity)...
  393.  
  394.     DVector vVel;
  395.     pServerDE->GetVelocity(m_hObject, &vVel);
  396.  
  397.     DVector vCurVel;
  398.     VEC_COPY(vCurVel, vVel);
  399.  
  400.     if (VEC_MAG(vCurVel) > 1.0f)
  401.     {
  402.         DVector vDir;
  403.         VEC_COPY(vDir, vCurVel);
  404.         VEC_NORM(vDir);
  405.  
  406.         DFLOAT fAdjust = pServerDE->GetFrameTime()*(m_fLadderVel/LADDER_STOP_TIME);
  407.  
  408.         VEC_MULSCALAR(vVel, vDir, fAdjust);
  409.  
  410.         if (VEC_MAG(vVel) < VEC_MAG(vCurVel))
  411.         {
  412.             VEC_SUB(vVel, vCurVel, vVel);
  413.         }
  414.         else
  415.         {
  416.             VEC_INIT(vVel);
  417.         }
  418.  
  419.         // If we're trapped, don't move...
  420.         if(m_nTrapped)
  421.             { VEC_INIT(vVel); }
  422.  
  423.         pServerDE->SetVelocity(m_hObject, &vVel);
  424.     }
  425.  
  426.     pCPStruct->m_Flags &= ~FLAG_GRAVITY;  // Turn gravity off
  427. }
  428.  
  429.  
  430.  
  431. // ----------------------------------------------------------------------- //
  432. //
  433. //    ROUTINE:    CBaseCharacter::Save
  434. //
  435. //    PURPOSE:    Save the object
  436. //
  437. // ----------------------------------------------------------------------- //
  438.  
  439. void CBaseCharacter::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveFlags)
  440. {
  441.     CServerDE* pServerDE = GetServerDE();
  442.     if (!pServerDE || !hWrite) return;
  443.  
  444. }
  445.  
  446.  
  447. // ----------------------------------------------------------------------- //
  448. //
  449. //    ROUTINE:    CBaseCharacter::Load
  450. //
  451. //    PURPOSE:    Load the object
  452. //
  453. // ----------------------------------------------------------------------- //
  454.  
  455. void CBaseCharacter::Load(HMESSAGEREAD hRead, DDWORD dwLoadFlags)
  456. {
  457.     CServerDE* pServerDE = GetServerDE();
  458.     if (!pServerDE || !hRead) return;
  459.  
  460. }
  461.  
  462.